﻿using System.Web.Mvc;
using System.Web.Routing;
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using NHibernate;
using WebSite.Config.Attributes;
using WebSite.Controllers;
using WebSite.Controllers.Plumbing;
using WebSite.Dal;

namespace WebSite
{
    public class MvcApplication : System.Web.HttpApplication
    {
        private IWindsorContainer _container;

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

			PatternRouteAttribute.MapDecoratedRoutes(routes);
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            BootstrapContainer();
        }

        protected void Application_End()
        {
            if (_container != null)
                _container.Dispose();
        }

        private void BootstrapContainer()
        {
            _container = new WindsorContainer();
            var controllerFactory = new WindsorControllerFactory(_container.Kernel);
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);

            // do registrations

            _container.Register(AllTypes.FromThisAssembly()
                .BasedOn<IController>()
                .If(Component.IsInSameNamespaceAs<HomeController>())
                .If(t => t.Name.EndsWith("Controller"))
                .Configure(t => t.LifestyleTransient()));

        	RegisterSessionFactory();
        }

    	private void RegisterSessionFactory()
    	{
			var config = PersistanceFactory.BuildDatabaseConfiguration();
			_container.Register(
				Component.For<ISessionFactory>()
					.UsingFactoryMethod(_ => config.BuildSessionFactory()),
				Component.For<ISession>()
					.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
					.LifestylePerWebRequest()
				);
    	}
    }
}